/*
 *  $Id: NamePhrasePart.cs 1180 2010-11-10 14:13:13Z thenn.erannor $
 *	This file is a part of Ragima CCG.
 *	(C) 2008-2010 Ragima development group.
 *
 *	Licensed under the terms of the GNU GPL License version 2.
 *
 */

namespace Ragima.Languages.PhraseParts {
    /// <summary>
    /// Абстрактная часть фразы с именем. Может быть с заглавной буквы.
    /// </summary>
    public abstract class NamePhrasePart : TypedArgPhrasePart<INamed> {
        private bool _capitalize;

        public NamePhrasePart(int argNum, bool capitalize): base(argNum) {
            _capitalize = capitalize;
        }

        /// <summary>
        /// Строит имя в соответствии с установкой заглавной буквы.
        /// </summary>
        protected void BuildName(PhraseBuilder builder, string name) {
            builder.AppendCapitalize(name, _capitalize);
        }

        protected override void BuildTemplateArg(PhraseBuilder builder) {
            builder.Text.Append(_capitalize ? char.ToUpper(PhraseTemplateSymbols.NameCommand) : PhraseTemplateSymbols.NameCommand);
            BuildTemplateCase(builder);
        }

        /// <summary>
        /// Строит в шаблон номер падежа.
        /// </summary>
        protected abstract void BuildTemplateCase(PhraseBuilder builder);

        /// <summary>
        /// Выдает сам аргумент как объект для хинта.
        /// </summary>
        protected override object GetHintObject(INamed arg) {
            return arg;
        }

        /// <summary>
        /// Абстрактный парсер для имени.
        /// </summary>
        public abstract class NameParser<TCase> : IPhrasePartParser {
            public bool NeedArgument {
                get { return true; }
            }

            public bool Test(PhraseTemplateScanner scanner) {
                return scanner.TestIgnoreCase(PhraseTemplateSymbols.NameCommand);
            }

            public PhrasePart Create(int argNum, PhraseTemplateScanner scanner) {
                var capitalize = char.IsUpper(scanner.GetChar());
                TCase nameCase = scanner.GetEnum<TCase>();
                return Create(argNum, capitalize, nameCase);
            }

            protected abstract PhrasePart Create(int argNum, bool capitalize, TCase nameCase);
        }
    }
}
